// main.c
// Created: 12-04-2011 by Pedro Mancheno
// Reader App

#include <stdio.h>
#include <Windows.h>

#define BUFSIZE 4096;

// We declare standard handles, two for read/writing the input and two for read/writing the output
HANDLE childInputReadHandle = NULL;
HANDLE childInputWriteHandle = NULL;
HANDLE childOutputReadHandle = NULL;
HANDLE childOutputWriteHandle = NULL;

HANDLE inputFile = NULL;

//FILE *file;   // Pointer to the file

// Function declaration
void CreateChildProcess(void);
void WriteToPipe(void);
void ReadFromPipe(void);
void ErrorExit(char* errorMessage);
//void ReadTextFile(const char *textFilePath);

void main(int argc, char *argv[])
{
	SECURITY_ATTRIBUTES securityAttributes;

	// Set the securityAttributes
	// The bInheritHandle flag should be true so pipe handles are inherited
	securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
	securityAttributes.bInheritHandle = TRUE;
	securityAttributes.lpSecurityDescriptor = NULL;


	// Create a pipe for the child process's standard OUTPUT
	if (!CreatePipe(&childOutputReadHandle, &childOutputWriteHandle, &securityAttributes, 0))
		ErrorExit("Error while creating the standard Output Handler");

	// Ensure the read handle to the pipe for standard OUTPUT is not inherited
	if (!SetHandleInformation(childOutputReadHandle, HANDLE_FLAG_INHERIT, 0))
		ErrorExit("The read handle for standard Output is inherited");

	// Create a pipe for the child process's standard INPUT
	if (!CreatePipe(&childInputReadHandle, &childInputWriteHandle, &securityAttributes, 0))
		ErrorExit("Error while creating the standard Input Handler");

	// Ensure the write handle to the pipe for standard INPUT is not inherited
	if (!SetHandleInformation(childInputWriteHandle, HANDLE_FLAG_INHERIT, 0))
		ErrorExit("The write handle for standard Input is inherited");

	// Now we create our child process
	CreateChildProcess();

	getchar();
}


// Creates a child process that uses the previously defined handles for standards input and output
void CreateChildProcess(void)
{
	TCHAR commandLine[] = TEXT("child");
	PROCESS_INFORMATION processInformation;
	STARTUPINFO startUpInformation;
	BOOL success = FALSE;

	// Set up members of the processInformation struct
	ZeroMemory(&processInformation, sizeof(PROCESS_INFORMATION));

	// Set up members of the startUpInformation struct
	// This structure specifies the standard input and output handles for redirection
	ZeroMemory(&startUpInformation, sizeof(STARTUPINFO));
	startUpInformation.cb = sizeof(STARTUPINFO);
	startUpInformation.hStdError = childOutputWriteHandle;
	startUpInformation.hStdOutput = childOutputWriteHandle;
	startUpInformation.hStdInput = childInputReadHandle;
	startUpInformation.dwFlags |= STARTF_USESTDHANDLES;

	
	// Create the child process
	success = CreateProcess(NULL,
		commandLine,			// commande line
		NULL,					// process security attributes
		NULL,					// primary thread security attributes
		FALSE,					// handles are inherited
		0,						// creation flags
		NULL,					// use parent's enviroment
		NULL,					// use parent's current directory
		&startUpInformation,	// STARTUPINFO pointer
		&processInformation);	// receives PROCESS_INFORMATION

	if(!success)
		ErrorExit("Error while creating a process");
		
	else {
		// Close handles to the child process and its primary thread.
		// Some applications might keep these handles to monitor the status
		// of the child process, for example.
		CloseHandle(processInformation.hProcess);
		CloseHandle(processInformation.hThread);
	}
}

/*void ReadTextFile(const char *textFilePath)
{
	char line[64]; // Line buffer

	file = fopen (textFilePath, "rt");

	// Parse the text file, line
	while(fgets(line, 64, file) != NULL)
	{
		/* get a line, up to 80 chars from fr.  done if NULL */
		/* print the string */
	/*	printf ("%s\n", line);
   }

   fclose(file);  /* close the file prior to exiting the routine */
/*}*/

void ErrorExit(char* errorMessage)
{
	printf(errorMessage);
}

